package il.technion.cs236369.proxy;

import java.io.IOException;
import org.apache.http.ConnectionClosedException;
import org.apache.http.HttpConnection;
import org.apache.http.HttpException;
import org.apache.http.HttpServerConnection;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpService;
import org.apache.log4j.Logger;

/**
 * <p>
 * Performs a request to server from browser client (using cache if needed)
 * </p>
 * 
 * @author Bikman Michael, 317920999, smbikman@t2
 */
public class Worker {

	private final HttpService httpservice;
	private final HttpServerConnection clientToProxyConn;
	private static long id = 1;
	private Logger sysLogger = Logger.getLogger(LogUtils.system);

	/**
	 * Instantiates a new worker.
	 * 
	 * @param httpservice
	 *            service for handling requests
	 * @param conn
	 *            connection from client to proxy server
	 */
	public Worker(final HttpService httpservice, final HttpServerConnection conn) {
		this.httpservice = httpservice;
		this.clientToProxyConn = conn;
	}

	/**
	 * Gets the request from remote server or proxy cache.
	 */
	public void run() {
		sysLogger.info("Worker " + id + " started...\n");
		HttpContext context = new BasicHttpContext(null);
		try {
			while (!Thread.interrupted() && clientToProxyConn.isOpen()) {

				httpservice.handleRequest(clientToProxyConn, context);

				// (Without it we have exceptions)
				try {
					sysLogger.info("Closing clientToProxy connection\n");
					if (clientToProxyConn != null)
						clientToProxyConn.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (ConnectionClosedException ex) {
			sysLogger.error("Client closed connection\n", ex);

		} catch (IOException ex) {
			sysLogger.error("I/O error: " + ex.getMessage() + "\n", ex);

		} catch (HttpException ex) {
			sysLogger.error("Unrecoverable HTTP protocol violation: " + ex.getMessage() + "\n", ex);
		} finally {
			try {
				sysLogger.info("Worker " + id + " ended...\n");
				id++;

				//
				sysLogger.info("Closing connToServer connection\n");
				if (context.getAttribute("connToServer") != null)
					((HttpConnection) context.getAttribute("connToServer")).close();

				// FIX: Close connection more than once
				// sysLogger.info("Closing socketToServer\n");
				// if (context.getAttribute("socketToServer") != null)
				// ((Socket) context.getAttribute("socketToServer")).close();

			} catch (IOException ignore) {
			}
		}
	}
}